package com.example.musicplayer.user;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

import com.example.musicplayer.DataLoadManager;
import com.example.musicplayer.MusicPlayerApplication;
import com.example.musicplayer.activity.MainActivity;
import com.example.musicplayer.commonUtils.StringUtil;
import com.example.musicplayer.musicTools.UserTableManager;
import com.example.musicplayer.provider.DBConstants;
import com.example.musicplayer.provider.MusicContentProvider;

import java.util.ArrayList;
import java.util.List;

public class UserManage {
    private static boolean sUserLogin = false;
    private static int sLastUserId = -1;
    private static final String URI_MUSIC = "content://com.example.musicplayer.provider.MusicContentProvider/";
    private static final ContentResolver RESOLVER;
    private static final Uri URI_USER;
    //record if confirm password successfully
    private static boolean sPasswordConfirmSuccess = false;

    static {
        URI_USER = Uri.parse(URI_MUSIC + DBConstants.User.TABLE_NAME);
        RESOLVER = MusicPlayerApplication.getInstance().getContentResolver();
    }

    //init an user
    public static boolean initUser(int id) {
        Cursor cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.ID, DBConstants.User.NAME
                        , DBConstants.User.PHOTO, DBConstants.User.VIP, DBConstants.User.GRADE
                        , DBConstants.User.AUTHORITY}, DBConstants.User.ID + "=?",
                new String[]{String.valueOf(id)}, null);
        if (cursor != null && cursor.moveToNext()) {
            String name = cursor.getString(cursor.getColumnIndex(DBConstants.User.NAME));
            int photo = cursor.getInt(cursor.getColumnIndex(DBConstants.User.PHOTO));
            int vip = cursor.getInt(cursor.getColumnIndex(DBConstants.User.VIP));
            int grade = cursor.getInt(cursor.getColumnIndex(DBConstants.User.GRADE));
            int authority = cursor.getInt(cursor.getColumnIndex(DBConstants.User.AUTHORITY));
            User.initUser(id, name, photo, vip, grade, authority);
            setUserLogin(true);
            setLastUserId(id);
            //update login state
            DataLoadManager.writeLoginState();
            //update the confirm state
            updatePasswordConfirmState();
            cursor.close();
            return true;
        }
        return false;
    }

    public static int registerUser(String userName, String password, String email) {
        int id = registerUserId();
        if (id > 0) {
            ContentValues values = new ContentValues();
            values.put(DBConstants.User.ID, id);
            values.put(DBConstants.User.NAME, userName);
            values.put(DBConstants.User.PASSWORD, password);
            values.put(DBConstants.User.EMAIL, email);
            values.put(DBConstants.User.PHOTO, 0);
            values.put(DBConstants.User.VIP, 0);
            values.put(DBConstants.User.DATE, StringUtil.getFormatDate());
            values.put(DBConstants.User.GRADE, 1);
            values.put(DBConstants.User.AUTHORITY, 0);
            values.put(DBConstants.User.DATA_1, "");
            values.put(DBConstants.User.DATA_2, "");
            synchronized (RESOLVER) {
                try {
                    RESOLVER.insert(URI_USER, values);
                } catch (Exception e) {
                    e.printStackTrace();
                    id = -1;
                }
            }
        }
        return id;
    }

    public static void deleteUser(int userId) {
        if (User.getInstance() == null) {
            synchronized (RESOLVER) {
                RESOLVER.delete(URI_USER, DBConstants.User.ID + "=?", new String[]{String.valueOf(userId)});
            }
        }
    }

    public static void deleteUserAndData(int userId) {
        User user = User.getInstance();
        if (user != null && user.hasAuthority() && userId != user.getUserId()) {
            Cursor cursor;
            //delete from table user
            synchronized (RESOLVER) {
                RESOLVER.delete(URI_USER, DBConstants.User.ID + "=?", new String[]{String.valueOf(userId)});
            }
            //delete table music_menu_detail_userId
            String tableName = DBConstants.MusicMenuManage.TABLE_NAME + userId;
            List<String> tableList = new ArrayList<String>();
            cursor = MusicContentProvider.getUserData(tableName, new String[]{DBConstants.MusicMenuManage.MENU_TABLE_NAME}
                    , null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    tableList.add(cursor.getString(cursor.getColumnIndex(DBConstants.MusicMenuManage.MENU_TABLE_NAME)));
                }
                cursor.close();
            }
            for (int i = 0; i < tableList.size(); i++) {
                MusicContentProvider.deleteUserData(tableList.get(i));
            }
            //delete table music_menu_manage_userId
            MusicContentProvider.deleteUserData(tableName);
            //delete table music_detail_userId
            tableName = DBConstants.MusicDetailUser.TABLE_NAME + userId;
            MusicContentProvider.deleteUserData(tableName);
        }
    }

    public static int checkLoginEvent(String name, String password) {
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.ID, DBConstants.User.NAME, DBConstants.User.PASSWORD}
                    , null, null, null);
        }
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String existName = cursor.getString(cursor.getColumnIndex(DBConstants.User.NAME));
                String existPassword = cursor.getString(cursor.getColumnIndex(DBConstants.User.PASSWORD));
                if (name.equals(existName) && password.equals(existPassword)) {
                    return cursor.getInt(cursor.getColumnIndex(DBConstants.User.ID));
                }
            }
            cursor.close();
        }
        return -1;
    }

    public static boolean checkPasswordProtect(String name, String answer) {
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.NAME, DBConstants.User.DATA_2}
                    , null, null, null);
        }
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String existName = cursor.getString(cursor.getColumnIndex(DBConstants.User.NAME));
                String existAnswer = cursor.getString(cursor.getColumnIndex(DBConstants.User.DATA_2));
                if (existName.equals(name) && existAnswer.equals(answer)) {
                    sPasswordConfirmSuccess = true;
                    return true;
                }
            }
            cursor.close();
        }
        return false;
    }

    public static boolean confirmPasswordForUser(String password) {
        if (password == null) {
            return false;
        }
        User user = User.getInstance();
        if (user == null) {
            return false;
        }
        final int id = user.getUserId();
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.PASSWORD}, DBConstants.User.ID + "=?"
                    , new String[]{String.valueOf(id)}, null);
        }
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                String rightPassword = cursor.getString(cursor.getColumnIndex(DBConstants.User.PASSWORD));
                sPasswordConfirmSuccess = password.equals(rightPassword);
                return sPasswordConfirmSuccess;
            }
            cursor.close();
        }
        return false;
    }

    public static String existUser(int userId) {
        String resultName = null;
        if (userId <= 0) {
            return resultName;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.ID, DBConstants.User.NAME}
                    , null, null, null);
        }
        if (cursor != null) {
            while (cursor.moveToNext()) {
                int existId = cursor.getInt(cursor.getColumnIndex(DBConstants.User.ID));
                String existName = cursor.getString(cursor.getColumnIndex(DBConstants.User.NAME));
                if (existId == userId) {
                    resultName = existName;
                    break;
                }
            }
            cursor.close();
        }
        return resultName;
    }

    public static boolean existUserName(String name) {
        if (name == null || name.equals("")) {
            return false;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.NAME}
                    , null, null, null);
        }
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String existName = cursor.getString(cursor.getColumnIndex(DBConstants.User.NAME));
                if (existName.equals(name)) {
                    cursor.close();
                    return true;
                }
            }
            cursor.close();
        }
        return false;
    }

    public static String getUserEmail() {
        String email = null;
        User user = User.getInstance();
        if (user == null) {
            return null;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.EMAIL}, DBConstants.User.ID + "=?"
                    , new String[]{String.valueOf(user.getUserId())}, null);
        }
        if (cursor != null) {
            if (cursor.moveToNext()) {
                email = cursor.getString(cursor.getColumnIndex(DBConstants.User.EMAIL));
            }
            cursor.close();
        }
        return email;
    }

    public static String getPasswordProtect(String name) {
        String question = "";
        if (name == null || name.equals("")) {
            return question;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.DATA_1}
                    , DBConstants.User.NAME + "=?"
                    , new String[]{name}, null);
        }
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                question = cursor.getString(cursor.getColumnIndex(DBConstants.User.DATA_1));
            }
            cursor.close();
        }
        return question;
    }

    public static String getPasswordProtect() {
        String question = "";
        User user = User.getInstance();
        if (user == null) {
            return question;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.DATA_1}, DBConstants.User.ID + "=?"
                    , new String[]{String.valueOf(user.getUserId())}, null);
        }
        if (cursor != null) {
            if (cursor.moveToNext()) {
                question = cursor.getString(cursor.getColumnIndex(DBConstants.User.DATA_1));
            }
            cursor.close();
        }
        return question;
    }

    public static String getPasswordProtectAnswer() {
        if (!isPasswordConfirmSuccess()) {
            return "";
        }
        String answer = "";
        User user = User.getInstance();
        if (user == null) {
            return answer;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.DATA_2}, DBConstants.User.ID + "=?"
                    , new String[]{String.valueOf(user.getUserId())}, null);
        }
        if (cursor != null) {
            if (cursor.moveToNext()) {
                answer = cursor.getString(cursor.getColumnIndex(DBConstants.User.DATA_2));
            }
            cursor.close();
        }
        return answer;
    }

    public static List<UserInfo> getAllUserInfo() {
        List<UserInfo> infoList = new ArrayList<UserInfo>();
        User user = User.getInstance();
        if (user == null || !user.hasAuthority()) {
            return infoList;
        }
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.ID, DBConstants.User.NAME
                            , DBConstants.User.EMAIL, DBConstants.User.PHOTO, DBConstants.User.VIP, DBConstants.User.GRADE}
                    , null, null, null);
        }
        if (cursor != null) {
            while (cursor.moveToNext()) {
                int id = cursor.getInt(cursor.getColumnIndex(DBConstants.User.ID));
                if (id != user.getUserId()) {
                    String name = cursor.getString(cursor.getColumnIndex(DBConstants.User.NAME));
                    String email = cursor.getString(cursor.getColumnIndex(DBConstants.User.EMAIL));
                    int photo = cursor.getInt(cursor.getColumnIndex(DBConstants.User.PHOTO));
                    int vip = cursor.getInt(cursor.getColumnIndex(DBConstants.User.VIP));
                    int grade = cursor.getInt(cursor.getColumnIndex(DBConstants.User.GRADE));
                    infoList.add(new UserInfo(id, name, email, photo, vip, grade));
                }
            }
            cursor.close();
        }
        return infoList;
    }

    private static List<Integer> getUserIdList() {
        List<Integer> idList = new ArrayList<Integer>();
        Cursor cursor;
        synchronized (RESOLVER) {
            cursor = RESOLVER.query(URI_USER, new String[]{DBConstants.User.ID}
                    , null, null, null);
        }
        if (cursor != null) {
            while (cursor.moveToNext()) {
                int id = cursor.getInt(cursor.getColumnIndex(DBConstants.User.ID));
                idList.add(id);
            }
            cursor.close();
        }
        return idList;
    }

    private static int registerUserId() {
        List<Integer> list = getUserIdList();
        if (list.size() == 0) {
            return 1;
        }
        int[] array = new int[list.size() + 2];
        for (int i = 0; i < list.size(); i++) {
            int id = list.get(i);
            if (id >= 1 && id <= list.size() + 1) {
                array[id] = -1;
            }
        }
        for (int i = 1; i < list.size() + 2; i++) {
            if (array[i] != -1) {
                return i;
            }
        }
        return -1;
    }

    public static void exitLoginState() {
        if (User.getInstance() != null) {
            if (DataLoadManager.getInstance() != null) {
                DataLoadManager.getInstance().writeBaseData();
            }
            MainActivity mainActivity = MusicPlayerApplication.getInstance().getMainActivity();
            if (mainActivity != null) {
                mainActivity.saveMusicPlayState();
            }
            //remove table for current user
            UserTableManager.removeTableForExitLogin();
            setUserLogin(false);
            User.exitLoginState();
            DataLoadManager.writeLoginState();
        }
    }

    public static boolean updatePassword(String newPassword) {
        if (!isPasswordConfirmSuccess()) {
            return false;
        }
        User user = User.getInstance();
        if (user == null) {
            return false;
        }
        int id = user.getUserId();
        ContentValues values = new ContentValues();
        values.put(DBConstants.User.PASSWORD, newPassword);
        synchronized (RESOLVER) {
            RESOLVER.update(URI_USER, values, DBConstants.User.ID + "=?", new String[]{String.valueOf(id)});
        }
        updatePasswordConfirmState();
        return true;
    }

    public static boolean updatePasswordForForget(String name, String newPassword) {
        if (!isPasswordConfirmSuccess()) {
            return false;
        }
        ContentValues values = new ContentValues();
        values.put(DBConstants.User.PASSWORD, newPassword);
        synchronized (RESOLVER) {
            RESOLVER.update(URI_USER, values, DBConstants.User.NAME + "=?", new String[]{name});
        }
        updatePasswordConfirmState();
        return true;
    }

    public static boolean updatePasswordProtect(String question, String answer) {
        if (!isPasswordConfirmSuccess()) {
            return false;
        }
        User user = User.getInstance();
        if (user == null) {
            return false;
        }
        int id = user.getUserId();
        ContentValues values = new ContentValues();
        values.put(DBConstants.User.DATA_1, question);
        values.put(DBConstants.User.DATA_2, answer);
        synchronized (RESOLVER) {
            RESOLVER.update(URI_USER, values, DBConstants.User.ID + "=?", new String[]{String.valueOf(id)});
        }
        return true;
    }

    public static boolean updateUserName(int userId, String newName) {
        User user = User.getInstance();
        if (user == null || user.getUserId() != userId) {
            return false;
        }
        ContentValues values = new ContentValues();
        values.put(DBConstants.User.NAME, newName);
        synchronized (RESOLVER) {
            RESOLVER.update(URI_USER, values, DBConstants.User.ID + "=?", new String[]{String.valueOf(userId)});
        }
        return true;
    }

    public static boolean updateUserPhoto(int photoId) {
        User user = User.getInstance();
        if (user == null || photoId < 0) {
            return false;
        }
        ContentValues values = new ContentValues();
        values.put(DBConstants.User.PHOTO, photoId);
        synchronized (RESOLVER) {
            RESOLVER.update(URI_USER, values, DBConstants.User.ID + "=?", new String[]{String.valueOf(user.getUserId())});
        }
        return true;
    }

    public static boolean isPasswordConfirmSuccess() {
        return sPasswordConfirmSuccess;
    }

    public static void updatePasswordConfirmState() {
        sPasswordConfirmSuccess = false;
    }

    public synchronized static void setUserLogin(boolean userLogin) {
        sUserLogin = userLogin;
    }

    public synchronized static boolean getUserLogin() {
        return sUserLogin;
    }

    public static void setLastUserId(int lastUserId) {
        sLastUserId = lastUserId;
    }

    public static int getLastUserId() {
        return sLastUserId;
    }
}